home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
COMAL
/
L-PET COMAL
/
(k)l1.d64
/
evaluator.l
< prev
next >
Wrap
Text File
|
2007-03-01
|
6KB
|
284 lines
0010 //
0020 // EXPRESSION EVALUATION
0030 //
0040 REPEAT
0050 ENTER'EXPR("ENTER EXPRESSION",X)
0060 PRINT "THE VALUE IS";X
0070 PRINT
0080 UNTIL FALSE
0090 HALT
0100 //
0110 PROC ENTER'EXPR(PROMPT$,REF VALUE) CLOSED
0120 DIM TEXT$ OF 80
0130 REPEAT // UNTIL LEGAL EXPRESSION //
0140 ERR:=FALSE
0150 REPEAT // DON'T ACCEPT A NULL STRING
0160 INPUT PROMPT$+": ": TEXT$
0170 UNTIL TEXT$>""
0180 IF TEXT$="STOP" THEN
0190 HALT
0200 ELSE
0210 VALUE:=EXPRESSION(TEXT$,ERR)
0220 ENDIF
0230 UNTIL NOT ERR
0240 ENDPROC ENTER'EXPR
0250 //
0260 FUNC EXPRESSION(TEXT$,REF ERR) CLOSED
0270 //
0280 DUMMY:=1
0290 //
0300 DIM EXPR$ OF LEN(TEXT$)+1, EOL$ OF 1
0310 DIM SYMBOL$ OF 10, CHAR$ OF 1
0320 //
0330 EOL$:=CHR$(13)
0340 EXPR$:=TEXT$+EOL$
0350 I:=1
0360 PI:=ATN(1)*4
0370 //
0380 NEXT'CHAR
0390 NEXT'SYMBOL
0400 VALUE:=SIMPLE'EXPR(DUMMY)
0410 MUSTBE(EOL$)
0420 //
0430 RETURN VALUE
0440 //
0450 ENDFUNC EXPRESSION
0460 //
0470 FUNC SIMPLE'EXPR(VALUE)
0480 IF SYMBOL$ IN "+-" THEN
0490 VALUE:=0
0500 ELSE
0510 VALUE:=TERM(DUMMY)
0520 ENDIF
0530 WHILE SYMBOL$ IN "+-" DO
0540 IF SYMBOL$="+" THEN
0550 NEXT'SYMBOL; VALUE:+TERM(DUMMY)
0560 ELSE
0570 NEXT'SYMBOL; VALUE:-TERM(DUMMY)
0580 ENDIF
0590 ENDWHILE
0600 RETURN VALUE
0610 ENDFUNC SIMPLE'EXPR
0620 //
0630 FUNC TERM(VALUE)
0640 VALUE:=FACTOR(DUMMY)
0650 WHILE SYMBOL$ IN "*/" DO
0660 IF SYMBOL$="*" THEN
0670 NEXT'SYMBOL; VALUE:=VALUE*FACTOR(DUMMY)
0680 ELSE
0690 NEXT'SYMBOL; VALUE:=VALUE/FACTOR(DUMMY)
0700 ENDIF
0710 ENDWHILE
0720 RETURN VALUE
0730 ENDFUNC TERM
0740 //
0750 FUNC FACTOR(VALUE)
0760 VALUE:=OPERAND(DUMMY)
0770 IF HAVE("^") THEN
0780 RETURN VALUE^FACTOR(DUMMY)
0790 ELSE
0800 RETURN VALUE
0810 ENDIF
0820 ENDFUNC FACTOR
0830 //
0840 FUNC OPERAND(VALUE)
0850 IF HAVE("<NUMBER>") THEN
0860 RETURN NUMBER
0870 ELIF HAVE("(") THEN
0880 VALUE:=SIMPLE'EXPR(DUMMY); MUSTBE(")")
0890 RETURN VALUE
0900 ELIF "A"<=SYMBOL$(1) AND SYMBOL$(1)<="Z" THEN
0910 RETURN FUNCTION'CALL(DUMMY)
0920 ELSE
0930 ERROR("OPERAND EXPECTED")
0940 RETURN DUMMY
0950 ENDIF
0960 ENDFUNC OPERAND
0970 //
0980 PROC MUSTBE(TOKEN$)
0990 IF TOKEN$=SYMBOL$ THEN
1000 NEXT'SYMBOL
1010 ELIF TOKEN$=EOL$ THEN
1020 ERROR(""""+SYMBOL$+""" NOT EXPECTED")
1030 ELIF SYMBOL$=EOL$ THEN
1040 ERROR(""""+TOKEN$+""" EXPECTED")
1050 ELSE
1060 ERROR(""""+TOKEN$+""" EXPECTED, NOT """+SYMBOL$+"""")
1070 ENDIF
1080 ENDPROC MUSTBE
1090 //
1100 FUNC HAVE(TOKEN$)
1110 IF TOKEN$=SYMBOL$ THEN
1120 NEXT'SYMBOL
1130 RETURN TRUE
1140 ELSE
1150 RETURN FALSE
1160 ENDIF
1170 ENDFUNC HAVE
1180 //
1190 PROC ERROR(MESSAGE$)
1200 IF NOT ERR THEN
1210 PRINT
1220 PRINT TEXT$
1230 PRINT TAB(I'-1),"^"
1240 PRINT "*** ",MESSAGE$," ***"
1250 PRINT
1260 ERR:=TRUE
1270 ENDIF
1280 ENDPROC ERROR
1290 //
1300 PROC NEXT'SYMBOL
1310 WHILE CHAR$=" " DO NEXT'CHAR
1320 I':=I
1330 IF CHAR$ IN "0123456789." THEN
1340 NUMBER:=VAL; SYMBOL$:="<NUMBER>"
1350 ELIF "A"<=CHAR$ AND CHAR$<="Z" THEN
1360 GET'IDENTIFIER
1370 ELSE
1380 SYMBOL$:=CHAR$; NEXT'CHAR
1390 ENDIF
1400 ENDPROC NEXT'SYMBOL
1410 //
1420 FUNC VAL // PARSE NUMBER AND RETURN VALUE
1430 X:=0 // ACCUMULATE IN X
1440 IF CHAR$="." THEN
1450 NEXT'CHAR
1460 I'':=I; POS:=10
1470 WHILE "0"<=CHAR$ AND CHAR$<="9" DO
1480 X:+(ORD(CHAR$)-ORD("0"))/POS; POS:=POS*10; NEXT'CHAR
1490 ENDWHILE
1500 IF I''=I THEN ERROR("FORMAT ERROR IN NUMBER")
1510 SCALE'FACTOR
1520 ELSE
1530 WHILE "0"<=CHAR$ AND CHAR$<="9" DO
1540 X:=X*10+ORD(CHAR$)-ORD("0"); NEXT'CHAR
1550 ENDWHILE
1560 IF CHAR$="." THEN
1570 NEXT'CHAR
1580 POS:=10
1590 WHILE "0"<=CHAR$ AND CHAR$<="9" DO
1600 X:+(ORD(CHAR$)-ORD("0"))/POS; POS:=POS*10; NEXT'CHAR
1610 ENDWHILE
1620 ENDIF
1630 SCALE'FACTOR
1640 ENDIF
1650 RETURN X
1660 ENDFUNC VAL
1670 //
1680 PROC SCALE'FACTOR
1690 IF CHAR$="E" THEN
1700 NEXT'CHAR
1710 IF CHAR$ IN "+-" THEN
1720 SIGN:=(CHAR$="+")-(CHAR$="-"); NEXT'CHAR
1730 ELSE
1740 SIGN:=1
1750 ENDIF
1760 I'':=I; EXPO:=0
1770 WHILE "0"<=CHAR$ AND CHAR$<="9" DO
1780 EXPO:=EXPO*10+ORD(CHAR$)-ORD("0"); NEXT'CHAR
1790 ENDWHILE
1800 IF I''=I THEN ERROR("EXPONENT ERROR IN NUMBER")
1810 X:=X*10^(SIGN*EXPO)
1820 ENDIF
1830 ENDPROC SCALE'FACTOR
1840 //
1850 PROC GET'IDENTIFIER
1860 WHILE "A"<=CHAR$ AND CHAR$<="Z" DO NEXT'CHAR
1870 SYMBOL$:=EXPR$(I'-1:I-2)
1880 ENDPROC GET'IDENTIFIER
1890 //
1900 PROC NEXT'CHAR
1910 IF I<=LEN(EXPR$) THEN
1920 CHAR$:=EXPR$(I)
1930 ELSE
1940 CHAR$:=EOL$
1950 ENDIF
1960 I:+1
1970 ENDPROC NEXT'CHAR
1980 //
1990 PROC HALT // HALT PROGRAM EXECUTION
2000 CLOSE
2010 END
2020 ENDPROC HALT
2030 //
2040 FUNC FUNCTION'CALL(VALUE)
2050 CASE SYMBOL$ OF
2060 WHEN "PI"
2070 NEXT'SYMBOL
2080 RETURN PI
2090 WHEN "E"
2100 NEXT'SYMBOL
2110 RETURN EXP(1)
2120 WHEN "SIN"
2130 RETURN SIN(RAD(PARAMETER))
2140 WHEN "COS"
2150 RETURN COS(RAD(PARAMETER))
2160 WHEN "TAN"
2170 RETURN TAN(RAD(PARAMETER))
2180 WHEN "RAD"
2190 RETURN RAD(PARAMETER)
2200 WHEN "DEG"
2210 RETURN DEG(PARAMETER)
2220 WHEN "SQRT"
2230 RETURN SQR(PARAMETER)
2240 WHEN "LN"
2250 RETURN LOG(PARAMETER)
2260 WHEN "LOG"
2270 RETURN LOG(PARAMETER)/LOG(10)
2280 WHEN "ARCSIN"
2290 RETURN DEG(ARCSIN(PARAMETER))
2300 WHEN "ARCCOS"
2310 RETURN DEG(ARCCOS(PARAMETER))
2320 WHEN "ARCTAN"
2330 RETURN DEG(ATN(PARAMETER))
2340 WHEN "EXP"
2350 RETURN EXP(PARAMETER)
2360 OTHERWISE
2370 ERROR("UNKNOWN IDENTIFIER")
2380 RETURN DUMMY
2390 ENDCASE
2400 ENDFUNC FUNCTION'CALL
2410 //
2420 FUNC RAD(X)
2430 RETURN X/180*PI
2440 ENDFUNC RAD
2450 //
2460 FUNC DEG(X)
2470 RETURN X/PI*180
2480 ENDFUNC DEG
2490 //
2500 FUNC PARAMETER
2510 NEXT'SYMBOL
2520 MUSTBE("(")
2530 VALUE:=SIMPLE'EXPR(DUMMY)
2540 MUSTBE(")")
2550 RETURN VALUE
2560 ENDFUNC PARAMETER
2570 //
2580 FUNC ARCSIN(X)
2590 IF ABS(X)=1 THEN
2600 RETURN PI/2*SGN(X)
2610 ELIF ABS(X)>1 THEN
2620 ARG'ERROR
2630 RETURN DUMMY
2640 ELSE
2650 RETURN ATN(X/SQR(1-X*X))
2660 ENDIF
2670 ENDFUNC ARCSIN
2680 //
2690 FUNC ARCCOS(X)
2700 IF X=0 THEN
2710 RETURN PI/2
2720 ELIF ABS(X)>1 THEN
2730 ARG'ERROR
2740 RETURN DUMMY
2750 ELSE
2760 RETURN ATN(SQR(1-X*X)/X)+(X<0)*PI
2770 ENDIF
2780 ENDFUNC ARCCOS
2790 //
2800 PROC ARG'ERROR
2810 ERROR("ILLEGAL FUNCTION ARGUMENT")
2820 ENDPROC ARG'ERROR
2830 //